﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Library
{
	class ScreenManager:DrawableGameComponent
	{
		#region Fields
		private List<GameScreen> _screens;
		private List<GameScreen> _screensToUpdate;
		private InputState inputState = new InputState(InputState.InputType.KeyboardOnly);
		private bool screensLoaded = false;
		public Matrix SpriteScale;
		public bool isInitialized = false;
		public SpriteBatch spriteBatch;
		public double ElapsedGameTime;
		#endregion
		
		#region Constructors
		public ScreenManager(Game game):base(game)
		{
			_screens = new List<GameScreen>();
			_screensToUpdate = new List<GameScreen>();
		}
		#endregion
		public override void Initialize()
		{
			base.Initialize();
			isInitialized = true;
		}
		#region Xna methods
		protected override void LoadContent()
		{
			base.LoadContent();
			spriteBatch = new SpriteBatch(GraphicsDevice);
			float screenscale = (float)GraphicsDevice.Viewport.Width / 800f;
			SpriteScale = Matrix.CreateScale(screenscale, screenscale, 1);
			foreach (GameScreen screen in _screens)
			{
				screen.LoadContent();
			}
			screensLoaded = true;
		}
		public override void Draw(GameTime gameTime)
		{
			if (screensLoaded)
			{
				base.Draw(gameTime);
				DrawScreens(gameTime);
			}
		}
		public override void Update(GameTime gameTime)
		{
			UpdateScreens(gameTime);
			ElapsedGameTime = gameTime.ElapsedGameTime.TotalMilliseconds;
		}
		#endregion

		#region Private Methods
		private void UpdateScreens(GameTime gameTime)
		{
			_screensToUpdate.Clear();
			//Find out which to update
			foreach (GameScreen gameScreen in _screens)
			{
				_screensToUpdate.Add(gameScreen);
			}

			bool covered = false;
			inputState.UpdateStates();
			while(_screensToUpdate.Count >0)
			{
				GameScreen gameScreen = _screensToUpdate[_screensToUpdate.Count-1];
				_screensToUpdate.RemoveAt(_screensToUpdate.Count - 1);
				gameScreen.UpdateState(gameTime,covered);
				if (gameScreen.state == GameScreen.ScreenState.Active)
				{
					gameScreen.HandleInput(inputState);
					gameScreen.Update(gameTime);
					if (!gameScreen.IsPopUp)
					{
						covered = true;
					}
				}
			}
			inputState.UpdatePrevStates();
			//FOR DEBUG
			if (inputState.IsKeyPressed(Keys.Escape)) { Game.Exit(); }
		}
		private void DrawScreens(GameTime gameTime)
		{
			foreach (GameScreen screen in _screens)
			{
				if (screen.state != GameScreen.ScreenState.Hidden)
				{
					screen.Draw(gameTime);
				}
			}
		}
		#endregion

		#region Public Methods
		public void AddScreen(GameScreen gameScreen)
		{
			gameScreen.screenManager = this;
			_screens.Add(gameScreen);
		}
		public void RemoveScreen(GameScreen gameScreen)
		{
			_screens.Remove(gameScreen);
			_screensToUpdate.Remove(gameScreen);
		}
		#endregion
	}
}
